#include <stdio.h>
#include <stdlib.h>
#include "la.h"

struct sListAsoc
{
	int tam;
	Tuple * arr;
	int tam_actual;
};

ListAsoc
la_empty(void)
{
	ListAsoc l;
	l = (ListAsoc) malloc (sizeof(struct sListAsoc));
	if (l!=NULL)
	{
		l -> tam = 0;
		l -> tam_actual = 10;
		l-> arr = (Tuple *) calloc ((l->tam_actual), sizeof(Tuple));
		if (l->arr==NULL)
		{
			free(l);
			exit(EXIT_FAILURE);
		}
	}
	else
		exit(EXIT_FAILURE);

return l;
}

void
la_add(ListAsoc l, Key k, Data d)
{
	Tuple t;
	int n;
	
	n = l->tam;
	t = tuple_fromKeyData(k,d);

	if (l->tam < (l->tam_actual))
	{
		(l->arr)[n] = t;
		(l->tam) += 1;
	}
	else
	{
		(l -> tam_actual) *= 2;
		(l->arr) = (Tuple *) realloc (l->arr,(l->tam_actual)*sizeof(Tuple));
		(l->arr)[n] = t;
		(l->tam) += 1;
	}
}


Bool
la_exists(ListAsoc l, Key k)
{
	Bool b;
	int n;
	Key k2;	
	b = FALSE;
	n = 0;
	while ((n<(l->tam)) && (!b))
	{
		k2 = tuple_fst((l->arr)[n]);
		if (key_eq(k,k2))
			b = TRUE;
		k2 = key_destroy(k2);
		n+=1;
	}
return b;
}
		

Data
la_search(ListAsoc l, Key k)
{
	Data d;
	Bool found;
	Key k2;
	int n;
	n = 0;
	found = FALSE;	
	if (la_exists(l,k))
	{
		while (n<(l->tam) && (!found))
		{
			k2 = tuple_fst((l->arr)[n]);
			if (key_eq(k,k2))
			{	
				d = tuple_snd((l->arr)[n]);
				found = TRUE;
			}
			n+=1;
			k2 = key_destroy(k2);
		}
	}
	else
		d = NULL;

return d;
}


void
la_del(ListAsoc l, Key k)
{
	int n;
	Key k2;
	/*Tuple aux;*/

	n = 0;
	
	if (la_exists(l,k))
	{
		while (n<(l->tam))
		{
			k2 = tuple_fst(l->arr[n]);
			if (key_eq(k,k2))
			{
				(l->arr[n]) = tuple_destroy(l->arr[n]);
				(l->arr[n]) = l->arr[(l->tam)-1];
				l->tam -= 1;
				/*aux = tuple_clone(l->arr[(l->tam)-1]);
				l->arr[(l->tam)-1] = tuple_destroy(l->arr[(l->tam)-1]);
				l->arr[n] = tuple_destroy(l->arr[n]);
				l->arr[n] = aux;
				l->tam -= 1;*/
			}
			k2 = key_destroy(k2);
			n+=1;
		}
	}
}	
		


int
la_length(ListAsoc l)
{
return (l->tam);
}

void
print_la(ListAsoc l)
{
	int i;
	Key k;
	Data d;
	char * s2;
	char * s1;
	i = 0;
	while (i<(l->tam))
	{
		s1 = (char *) calloc (key_maxLen(),sizeof(char));
		if (s1 != NULL)
		{
			k = tuple_fst(l->arr[i]);
			d = tuple_snd(l->arr[i]);
			key_toString(k,s1);
			s2 = data_toString(d);
			printf("%s: %s\n",s1,s2);
			k = key_destroy(k);
			d = data_destroy(d);
			free(s2);
			free(s1);
			s2 = NULL;
			s1 = NULL;
			i += 1;
		}
	}
}

ListAsoc
la_destroy(ListAsoc l)
{
	int i;
	i = 0;	
	if (l!=NULL)
	{
		while(i<(l->tam))
		{		
			(l->arr)[i] = tuple_destroy((l->arr)[i]);
			i+=1;
		}
		free(l->arr);
		l->arr = NULL;
		free(l);
		l = NULL;
	}
return l;
}
